import 'package:hrt/entities/body_part.dart';
import 'package:hrt/entities/fight_result.dart';
import 'package:hrt/resources/app_colors.dart';
import 'package:hrt/resources/app_icons.dart';
import 'package:hrt/resources/app_images.dart';
import 'package:hrt/widgets/action_button.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

class FightPage extends StatefulWidget {
  const FightPage({Key? key}) : super(key: key);

  @override
  FightPageState createState() => FightPageState();
}

class FightPageState extends State<FightPage> {
  static const int _maxLives = 5;
  BodyPart? _defendingBodyPart;
  BodyPart? _attackingBodyPart;
  BodyPart _whatEnemyDefends = BodyPart.random();
  BodyPart _whatEnemyAttacks = BodyPart.random();
  int _youLives = _maxLives;
  int _enemyLives = _maxLives;
  String _centerText = "";

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: AppColors.background,
      body: Center(
        child: ConstrainedBox(
          constraints: const BoxConstraints(maxWidth: 800),
          child: Column(
            children: [
              _FightersInfo(
                maxLivesCount: _maxLives,
                youLivesCount: _youLives,
                enemyLivesCount: _enemyLives,
              ),
              Expanded(
                child: Padding(
                  padding: const EdgeInsets.symmetric(
                    horizontal: 16,
                    vertical: 30,
                  ),
                  child: ColoredBox(
                    color: AppColors.darkPurple,
                    child: SizedBox(
                      width: double.infinity,
                      child: Center(
                        child: Text(
                          _centerText,
                          textAlign: TextAlign.center,
                          style: const TextStyle(
                            fontSize: 18,
                            color: AppColors.darkGreyText,
                          ),
                        ),
                      ),
                    ),
                  ),
                ),
              ),
              _ControlsWidget(
                defendingBodyPart: _defendingBodyPart,
                selectDefendingBodyPart: _selectDefendingBodyPart,
                attackingBodyPart: _attackingBodyPart,
                selectAttackingBodyPart: _selectAttackingBodyPart,
              ),
              const SizedBox(height: 14),
              ActionButton(
                text: _isLivesCountZero() ? "返回首页" : "攻击！",
                onTap: _onGoButtonClicked,
                color: _getGoButtonColor(),
              ),
              const SizedBox(height: 16),
            ],
          ),
        ),
      ),
    );
  }

  Color _getGoButtonColor() {
    if (_isLivesCountZero()) {
      return AppColors.blackButton;
    } else if (!_isAllBodyPartsSelected()) {
      return AppColors.greyButton;
    } else {
      return AppColors.blackButton;
    }
  }

  bool _isAllBodyPartsSelected() {
    return _defendingBodyPart != null && _attackingBodyPart != null;
  }

  bool _isLivesCountZero() {
    return _youLives == 0 || _enemyLives == 0;
  }

  void _onGoButtonClicked() {
    if (_isLivesCountZero()) {
      Navigator.of(context).pop();
    } else if (_isAllBodyPartsSelected()) {
      setState(() {
        final bool enemyLoseLife = _attackingBodyPart != _whatEnemyDefends;
        final bool youLoseLife = _defendingBodyPart != _whatEnemyAttacks;

        if (enemyLoseLife) {
          _enemyLives--;
        }
        if (youLoseLife) {
          _youLives--;
        }

        final FightResult? fightResult =
            FightResult.calculateResult(_youLives, _enemyLives);
        if (fightResult != null) {
          SharedPreferences.getInstance().then((sharedPreferences) {
            sharedPreferences.setString(
              "last_fight_result",
              fightResult.result,
            );
            final String key = "stats_${fightResult.result.toLowerCase()}";
            final int currentValue = sharedPreferences.getInt(key) ?? 0;
            sharedPreferences.setInt(key, currentValue + 1);
          });
        }
        _centerText = _calculateCenterText(youLoseLife, enemyLoseLife);

        _whatEnemyDefends = BodyPart.random();
        _whatEnemyAttacks = BodyPart.random();

        _defendingBodyPart = null;
        _attackingBodyPart = null;
      });
    }
  }

  String _calculateCenterText(
    final bool youLoseLife,
    final bool enemyLoseLife,
  ) {
    if (_youLives == 0 && _enemyLives == 0) {
      return "平局";
    } else if (_enemyLives == 0) {
      return "你赢了！";
    } else if (_youLives == 0) {
      return "你输了~";
    } else {
      final String first = enemyLoseLife
          ? "你攻击了敌方的 ${_attackingBodyPart!.name.toLowerCase()}。"
          : "你的攻击落空了！";
      final String second = youLoseLife
          ? "敌方伤害了你的 ${_whatEnemyAttacks.name.toLowerCase()}！"
          : "敌方的攻击被你防御住了！";

      return "$first\n$second";
    }
  }

  void _selectDefendingBodyPart(final BodyPart value) {
    if (_isLivesCountZero()) {
      return;
    }
    setState(() {
      _defendingBodyPart = value;
    });
  }

  void _selectAttackingBodyPart(final BodyPart value) {
    if (_isLivesCountZero()) {
      return;
    }
    setState(() {
      _attackingBodyPart = value;
    });
  }
}

class _ControlsWidget extends StatelessWidget {
  const _ControlsWidget({
    Key? key,
    required this.defendingBodyPart,
    required this.selectDefendingBodyPart,
    required this.attackingBodyPart,
    required this.selectAttackingBodyPart,
  }) : super(key: key);

  final BodyPart? defendingBodyPart;
  final ValueSetter<BodyPart> selectDefendingBodyPart;
  final BodyPart? attackingBodyPart;
  final ValueSetter<BodyPart> selectAttackingBodyPart;

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        const SizedBox(width: 16),
        Expanded(
          child: Column(
            children: [
              Text(
                "防御".toUpperCase(),
                style: const TextStyle(color: AppColors.darkGreyText),
              ),
              const SizedBox(height: 13),
              _BodyPartButton(
                bodyPart: BodyPart.head,
                selected: defendingBodyPart == BodyPart.head,
                bodyPartSetter: selectDefendingBodyPart,
              ),
              const SizedBox(height: 14),
              _BodyPartButton(
                bodyPart: BodyPart.torso,
                selected: defendingBodyPart == BodyPart.torso,
                bodyPartSetter: selectDefendingBodyPart,
              ),
              const SizedBox(height: 14),
              _BodyPartButton(
                bodyPart: BodyPart.legs,
                selected: defendingBodyPart == BodyPart.legs,
                bodyPartSetter: selectDefendingBodyPart,
              ),
            ],
          ),
        ),
        const SizedBox(width: 12),
        Expanded(
          child: Column(
            children: [
              Text(
                "攻击".toUpperCase(),
                style: const TextStyle(color: AppColors.darkGreyText),
              ),
              const SizedBox(height: 13),
              _BodyPartButton(
                bodyPart: BodyPart.head,
                selected: attackingBodyPart == BodyPart.head,
                bodyPartSetter: selectAttackingBodyPart,
              ),
              const SizedBox(height: 14),
              _BodyPartButton(
                bodyPart: BodyPart.torso,
                selected: attackingBodyPart == BodyPart.torso,
                bodyPartSetter: selectAttackingBodyPart,
              ),
              const SizedBox(height: 14),
              _BodyPartButton(
                bodyPart: BodyPart.legs,
                selected: attackingBodyPart == BodyPart.legs,
                bodyPartSetter: selectAttackingBodyPart,
              ),
            ],
          ),
        ),
        const SizedBox(width: 16),
      ],
    );
  }
}

class _FightersInfo extends StatelessWidget {
  const _FightersInfo({
    Key? key,
    required this.maxLivesCount,
    required this.youLivesCount,
    required this.enemyLivesCount,
  }) : super(key: key);

  final int maxLivesCount;
  final int youLivesCount;
  final int enemyLivesCount;

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 190,
      child: Stack(
        children: [
          Row(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: const [
              Expanded(child: ColoredBox(color: AppColors.white)),
              Expanded(
                child: DecoratedBox(
                  decoration: BoxDecoration(
                    gradient: LinearGradient(
                      colors: [AppColors.white, AppColors.darkPurple],
                    ),
                  ),
                ),
              ),
              Expanded(child: ColoredBox(color: AppColors.darkPurple))
            ],
          ),
          Container(
            padding: EdgeInsets.only(top: 30),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children: [
                _LivesWidget(
                  overallLivesCount: maxLivesCount,
                  currentLivesCount: youLivesCount,
                ),
                Column(
                  children: [
                    const SizedBox(height: 16),
                    const Text(
                      "玩家",
                      style: TextStyle(color: AppColors.darkGreyText),
                    ),
                    const SizedBox(height: 12),
                    Image.asset(
                      AppImages.youAvatar,
                      width: 90,
                      height: 90,
                    )
                  ],
                ),
                const SizedBox(
                  height: 44,
                  width: 44,
                  child: DecoratedBox(
                    decoration: BoxDecoration(
                      shape: BoxShape.circle,
                      color: AppColors.blueButton,
                    ),
                    child: Center(
                      child: Text(
                        "vs",
                        style: TextStyle(
                          color: AppColors.whiteText,
                          fontSize: 16,
                        ),
                      ),
                    ),
                  ),
                ),
                Column(
                  children: [
                    const SizedBox(height: 16),
                    const Text(
                      "敌方",
                      style: TextStyle(color: AppColors.darkGreyText),
                    ),
                    const SizedBox(height: 12),
                    Image.asset(
                      AppImages.enemyAvatar,
                      width: 90,
                      height: 90,
                    )
                  ],
                ),
                _LivesWidget(
                  overallLivesCount: maxLivesCount,
                  currentLivesCount: enemyLivesCount,
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

class _LivesWidget extends StatelessWidget {
  const _LivesWidget({
    Key? key,
    required this.overallLivesCount,
    required this.currentLivesCount,
  })  : assert(overallLivesCount >= 1),
        assert(currentLivesCount >= 0),
        assert(currentLivesCount <= overallLivesCount),
        super(key: key);

  final int overallLivesCount;
  final int currentLivesCount;

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: List.generate(overallLivesCount, (index) {
        if (index < currentLivesCount) {
          return [
            Image.asset(AppIcons.heartFull, width: 18, height: 18),
            if (overallLivesCount - 1 > index) const SizedBox(height: 4),
          ];
        } else {
          return [
            Image.asset(AppIcons.heartEmpty, width: 18, height: 18),
            if (overallLivesCount - 1 > index) const SizedBox(height: 4),
          ];
        }
      }).expand((element) => element).toList(),
    );
  }
}

class _BodyPartButton extends StatelessWidget {
  const _BodyPartButton({
    Key? key,
    required this.bodyPart,
    required this.selected,
    required this.bodyPartSetter,
  }) : super(key: key);

  final BodyPart bodyPart;
  final bool selected;
  final ValueSetter<BodyPart> bodyPartSetter;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () => bodyPartSetter(bodyPart),
      child: SizedBox(
        height: 40,
        child: DecoratedBox(
          decoration: BoxDecoration(
            color: selected ? AppColors.blueButton : Colors.transparent,
            border: !selected
                ? Border.all(color: AppColors.darkGreyText, width: 2)
                : null,
          ),
          child: Center(
            child: Text(
              bodyPart.name.toUpperCase(),
              style: TextStyle(
                fontSize: 13,
                color: selected ? AppColors.whiteText : AppColors.darkGreyText,
              ),
            ),
          ),
        ),
      ),
    );
  }
}
